home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / nslookup / debug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-11-27  |  8.8 KB  |  400 lines

  1. /*
  2.  * Copyright (c) 1985 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. static char sccsid[] = "@(#)debug.c    5.13 (Berkeley) 6/18/88";
  20. #endif /* not lint */
  21.  
  22. /*
  23.  *******************************************************************************
  24.  *
  25.  *  debug.c --
  26.  *
  27.  *    Routines to print out packets received from a name server query.
  28.  *
  29.  *      Modified version of 4.3BSD BIND res_debug.c 5.6 9/14/85
  30.  *
  31.  *******************************************************************************
  32.  */
  33.  
  34. #include <sys/types.h>
  35. #include <netinet/in.h>
  36. #include <stdio.h>
  37. #include <arpa/nameser.h>
  38. #include <resolv.h>
  39. #include <netdb.h>
  40. #include "res.h"
  41.  
  42. extern char ctime();
  43.  
  44. /*
  45.  *  Imported from res_debug.c
  46.  */
  47. extern char *_res_resultcodes[];
  48. extern char *_res_opcodes[];
  49.  
  50. /*
  51.  *  Used to highlight the start of a record when printing it.
  52.  */
  53. #define INDENT "    ->  "
  54.  
  55.  
  56.  
  57. /*
  58.  * Print the contents of a query.
  59.  * This is intended to be primarily a debugging routine.
  60.  */
  61.  
  62. Print_query(msg, eom, printHeader)
  63.     char *msg, *eom;
  64.     int printHeader;
  65. {
  66.     Fprint_query(msg, eom, printHeader,stdout);
  67. }
  68.  
  69. Fprint_query(msg, eom, printHeader,file)
  70.     char *msg, *eom;
  71.     int printHeader;
  72.     FILE *file;
  73. {
  74.     register char *cp;
  75.     register HEADER *hp;
  76.     register int n;
  77.     short class;
  78.     short type;
  79.  
  80.     /*
  81.      * Print header fields.
  82.      */
  83.     hp = (HEADER *)msg;
  84.     cp = msg + sizeof(HEADER);
  85.     if (printHeader || (_res.options & RES_DEBUG2)) {
  86.         fprintf(file,"    HEADER:\n");
  87.         fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
  88.         fprintf(file,", id = %d", ntohs(hp->id));
  89.         fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
  90.         fprintf(file,"\theader flags: ");
  91.         if (hp->qr) {
  92.             fprintf(file," response");
  93.         } else {
  94.             fprintf(file," query");
  95.         }
  96.         if (hp->aa)
  97.             fprintf(file,", auth. answer");
  98.         if (hp->tc)
  99.             fprintf(file,", truncation");
  100.         if (hp->rd)
  101.             fprintf(file,", want recursion");
  102.         if (hp->ra)
  103.             fprintf(file,", recursion avail.");
  104.         if (hp->pr)
  105.             fprintf(file,", primary");
  106.         fprintf(file,"\n\tquestions = %d", ntohs(hp->qdcount));
  107.         fprintf(file,",  answers = %d", ntohs(hp->ancount));
  108.         fprintf(file,",  auth. records = %d", ntohs(hp->nscount));
  109.         fprintf(file,",  additional = %d\n\n", ntohs(hp->arcount));
  110.     }
  111.  
  112.     /*
  113.      * Print question records.
  114.      */
  115.     if (n = ntohs(hp->qdcount)) {
  116.         fprintf(file,"    QUESTIONS:\n");
  117.         while (--n >= 0) {
  118.             fprintf(file,"\t");
  119.             cp = Print_cdname(cp, msg, eom, file);
  120.             if (cp == NULL)
  121.                 return;
  122.             type = _getshort(cp);
  123.             cp += sizeof(u_short);
  124.             class = _getshort(cp);
  125.             cp += sizeof(u_short);
  126.             fprintf(file,", type = %s", p_type(type));
  127.             fprintf(file,", class = %s\n", p_class(class));
  128.         }
  129.     }
  130.     /*
  131.      * Print authoritative answer records
  132.      */
  133.     if (n = ntohs(hp->ancount)) {
  134.         fprintf(file,"    ANSWERS:\n");
  135.         while (--n >= 0) {
  136.             fprintf(file, INDENT);
  137.             cp = Print_rr(cp, msg, eom, file);
  138.             if (cp == NULL)
  139.                 return;
  140.         }
  141.     }
  142.     /*
  143.      * print name server records
  144.      */
  145.     if (n = ntohs(hp->nscount)) {
  146.         fprintf(file,"    NAME SERVERS:\n");
  147.         while (--n >= 0) {
  148.             fprintf(file, INDENT);
  149.             cp = Print_rr(cp, msg, eom, file);
  150.             if (cp == NULL)
  151.                 return;
  152.         }
  153.     }
  154.     /*
  155.      * print additional records
  156.      */
  157.     if (n = ntohs(hp->arcount)) {
  158.         fprintf(file,"    ADDITIONAL RECORDS:\n");
  159.         while (--n >= 0) {
  160.             fprintf(file, INDENT);
  161.             cp = Print_rr(cp, msg, eom, file);
  162.             if (cp == NULL)
  163.                 return;
  164.         }
  165.     }
  166.     fprintf(file,"\n------------\n");
  167.  
  168. }
  169.  
  170.  
  171. char *
  172. Print_cdname_sub(cp, msg, eom, file, format)
  173.     char *cp, *msg, *eom;
  174.     FILE *file;
  175.     int format;
  176. {
  177.     int n;
  178.     char name[MAXDNAME];
  179.     extern char *strcpy();
  180.  
  181.     if ((n = dn_expand(msg, eom, cp, name, sizeof(name))) < 0)
  182.         return (NULL);
  183.     if (name[0] == '\0') {
  184.         (void) strcpy(name, "(root)");
  185.     }
  186.     if (format) {
  187.         fprintf(file, "%-30s", name);
  188.     } else {
  189.         fputs(name, file);
  190.     }
  191.     return (cp + n);
  192. }
  193.  
  194. char *
  195. Print_cdname(cp, msg, eom, file)
  196.     char *cp, *msg, *eom;
  197.     FILE *file;
  198. {
  199.     return(Print_cdname_sub(cp, msg, eom, file, 0));
  200. }
  201.  
  202. char *
  203. Print_cdname2(cp, msg, eom, file)
  204.     char *cp, *msg, *eom;
  205.     FILE *file;
  206. {
  207.     return(Print_cdname_sub(cp, msg, eom, file, 1));
  208. }
  209.  
  210. /*
  211.  * Print resource record fields in human readable form.
  212.  */
  213. char *
  214. Print_rr(cp, msg, eom, file)
  215.     char *cp, *msg, *eom;
  216.     FILE *file;
  217. {
  218.     int type, class, dlen, n, c;
  219.     long ttl;
  220.     struct in_addr inaddr;
  221.     char *cp1;
  222.  
  223.     if ((cp = Print_cdname(cp, msg, eom, file)) == NULL) {
  224.         fprintf(file, "(name truncated?)\n");
  225.         return (NULL);            /* compression error */
  226.     }
  227.  
  228.     type = _getshort(cp);
  229.     cp += sizeof(u_short);
  230.     class = _getshort(cp);
  231.     cp += sizeof(u_short);
  232.     ttl = _getlong(cp);
  233.     cp += sizeof(u_long);
  234.     dlen = _getshort(cp);
  235.     cp += sizeof(u_short);
  236.  
  237.     if (_res.options & RES_DEBUG2) {
  238.         fprintf(file,"\n\ttype = %s, class = %s, ttl = %s, dlen = %d",
  239.             p_type(type), p_class(class), p_time(ttl), dlen);
  240.         fprintf(file,"\n");
  241.     }
  242.  
  243.     cp1 = cp;
  244.  
  245.     /*
  246.      * Print type specific data, if appropriate
  247.      */
  248.     switch (type) {
  249.     case T_A:
  250.         switch (class) {
  251.         case C_IN:
  252.             bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  253.             if (dlen == 4) {
  254.                 fprintf(file,"\tinet address = %s\n",
  255.                     inet_ntoa(inaddr));
  256.                 cp += dlen;
  257.             } else if (dlen == 7) {
  258.                 fprintf(file,"\tinet address = %s",
  259.                     inet_ntoa(inaddr));
  260.                 fprintf(file,", protocol = %d", cp[4]);
  261.                 fprintf(file,", port = %d\n",
  262.                     (cp[5] << 8) + cp[6]);
  263.                 cp += dlen;
  264.             }
  265.             break;
  266.         default:
  267.             fprintf(file,"\taddress, class = %d, len = %d\n",
  268.                 class, dlen);
  269.         }
  270.         break;
  271.  
  272.     case T_CNAME:
  273.         fprintf(file,"\tcanonical name = ");
  274.         goto doname;
  275.  
  276.     case T_MX:
  277.         fprintf(file,"\tpreference = %d",_getshort(cp));
  278.         cp += sizeof(u_short);
  279.         fprintf(file,", mail exchanger = ");
  280.         goto doname;
  281.  
  282.     case T_MG:
  283.         fprintf(file,"\tmail group member = ");
  284.         goto doname;
  285.     case T_MB:
  286.         fprintf(file,"\tmail box = ");
  287.         goto doname;
  288.     case T_MR:
  289.         fprintf(file,"\tmailbox rename = ");
  290.         goto doname;
  291.     case T_NS:
  292.         fprintf(file,"\tnameserver = ");
  293.         goto doname;
  294.     case T_PTR:
  295.         fprintf(file,"\thost name = ");
  296. doname:
  297.         cp = Print_cdname(cp, msg, eom, file);
  298.         fprintf(file,"\n");
  299.         break;
  300.  
  301.     case T_HINFO:
  302.         if (n = *cp++) {
  303.             fprintf(file,"\tCPU=%.*s", n, cp);
  304.             cp += n;
  305.         }
  306.         if (n = *cp++) {
  307.             fprintf(file,"\tOS=%.*s\n", n, cp);
  308.             cp += n;
  309.         }
  310.         break;
  311.  
  312.     case T_SOA:
  313.         fprintf(file,"\torigin = ");
  314.         cp = Print_cdname(cp, msg, eom, file);
  315.         fprintf(file,"\n\tmail addr = ");
  316.         cp = Print_cdname(cp, msg, eom, file);
  317.         fprintf(file,"\n\tserial=%ld", _getlong(cp));
  318.         cp += sizeof(u_long);
  319.         fprintf(file,", refresh=%s", p_time(_getlong(cp)));
  320.         cp += sizeof(u_long);
  321.         fprintf(file,", retry=%s\n", p_time(_getlong(cp)));
  322.         cp += sizeof(u_long);
  323.         fprintf(file,"\texpire=%s", p_time(_getlong(cp)));
  324.         cp += sizeof(u_long);
  325.         fprintf(file,", min=%s\n", p_time(_getlong(cp)));
  326.         cp += sizeof(u_long);
  327.         break;
  328.  
  329.     case T_MINFO:
  330.         fprintf(file,"\trequests = ");
  331.         cp = Print_cdname(cp, msg, eom, file);
  332.         fprintf(file,"\n\terrors = ");
  333.         cp = Print_cdname(cp, msg, eom, file);
  334.         break;
  335.  
  336.     case T_UINFO:
  337.         fprintf(file,"\t%s\n", cp);
  338.         cp += dlen;
  339.         break;
  340.  
  341.     case T_UID:
  342.     case T_GID:
  343.         if (dlen == 4) {
  344.             fprintf(file,"\t%cid %ld\n", type == T_UID ? 'u' : 'g',
  345.                 _getlong(cp));
  346.             cp += sizeof(int);
  347.         } else
  348.             fprintf(file,"\t%cid of length %ld?\n",
  349.                 type == T_UID ? 'u' : 'g', dlen);
  350.         break;
  351.  
  352.     case T_WKS: {
  353.         struct protoent *protoPtr;
  354.  
  355.         if (dlen < sizeof(u_long) + 1)
  356.             break;
  357.         bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  358.         cp += sizeof(u_long);
  359.         if ((protoPtr = getprotobynumber(*cp)) != NULL) {
  360.             fprintf(file,"\tinet address = %s, protocol = %s\n\t",
  361.             inet_ntoa(inaddr), protoPtr->p_name);
  362.         } else {
  363.             fprintf(file,"\tinet address = %s, protocol = %d\n\t",
  364.             inet_ntoa(inaddr), *cp);
  365.         }
  366.         cp++;
  367.         n = 0;
  368.         while (cp < cp1 + dlen) {
  369.             c = *cp++;
  370.             do {
  371.                 struct servent *s;
  372.  
  373.                  if (c & 0200) {
  374.                     s = getservbyport(n, NULL);
  375.                     if (s != NULL) {
  376.                         fprintf(file,"  %s", s->s_name);
  377.                     } else {
  378.                         fprintf(file," #%d", n);
  379.                     }
  380.                 }
  381.                  c <<= 1;
  382.             } while (++n & 07);
  383.         }
  384.         putc('\n',file);
  385.         }
  386.         break;
  387.  
  388.     case T_NULL:
  389.         fprintf(file, "(type NULL, dlen %d)\n", dlen);
  390.         break;
  391.  
  392.     default:
  393.         fprintf(file,"\t???\n");
  394.         cp += dlen;
  395.     }
  396.     if (cp != cp1 + dlen)
  397.         fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen);
  398.     return (cp);
  399. }
  400.